<script setup lang="ts" name="GoodsSku">
import { PropType } from "vue";
import { GoodsInfo, Spec, SpecValue } from "@/types/goods";
// import { bwPowerSet } from "@/utils/bwPowerSet.ts";
import bwPowerSet from "@/utils/power-set";
const props = defineProps({
  goods: {
    type: Object as PropType<GoodsInfo>,
    required: true,
  },
});

const emit = defineEmits<{
  (e: "changeSku", skuId: string): void;
}>();

// 得到可使用sku（库存量大于0）的路径字典
const getPathMap = () => {
  const pathMap: any = {};

  // 1. 根据后台返回的skus得到有效sku组合
  const skus = props.goods.skus.filter((item) => item.inventory > 0);

  // console.log("skus", skus);

  skus.forEach((item) => {
    const arr = item.specs.map((sub) => sub.valueName);
    // console.log("skuId---arr", item.id, arr);

    // 3. 求上面数组的幂集
    const powerSet = bwPowerSet(arr);
    // console.log(powerSet);

    // 4. 把这些powerSet合并到一个路径字典中
    powerSet.forEach((v) => {
      const key = v.join("★");
      // console.log("---key---", key);
      if (key in pathMap) {
        // 之前有
        pathMap[key].push(item.id);
      } else {
        // 之前没有
        pathMap[key] = [item.id];
      }
    });
  });

  // console.log("---pathMap---", pathMap);
  return pathMap;
};

// 得到有效的商品skus集合组成的字典
const pathMap = getPathMap();

// 设置specs中每个按钮的禁用状态
const updateDisabledStatus = (specs: Spec[], pathMap: {}) => {
  const selectedSpec = getSelectedSpec(specs);
  // console.log("---selectedSpec---", selectedSpec);

  // 遍历每个specs中的值，然后把它的valueName拿到，
  specs.forEach((item, index) => {
    item.values.forEach((subitem) => {
      // 获取用户选择的规格【蓝色、日本、30cm】
      const selectedSpec = getSelectedSpec(specs);

      selectedSpec[index] = subitem.name;
      // console.log("---selectedSpec---", selectedSpec);

      const key = selectedSpec.filter((item) => item).join("★");
      // console.log("---key---", key);

      if (key in pathMap) {
        // 存在，有库存量
        subitem.disabled = false;
      } else {
        // 不存在则禁用
        subitem.disabled = true;
      }
    });
  });
};

// 获取选中的规格值
const getSelectedSpec = (specs: Spec[]) => {
  const arr: string[] = [];
  specs.forEach((item) => {
    const selectedSub = item.values.find((sub) => sub.selected);

    arr.push(selectedSub ? selectedSub.name : "");
  });

  return arr;
};

// 切换选中
const toggleSelect = (spec: Spec, specValue: SpecValue) => {
  // 默认禁用时，直接退出
  if (specValue.disabled) return;

  if (specValue.selected) {
    specValue.selected = false;
  } else {
    spec.values.forEach((item) => (item.selected = false));
    specValue.selected = true;
  }

  // 切换选中，需要重新获取 路径字典 pathMap
  const pathMap = getPathMap();

  // 点击每个规格后，都需要更新禁用状态
  updateDisabledStatus(props.goods.specs, pathMap);

  // 判断你是否全部选择了规格，如果全部选择了，则获取对应的skuId
  // 然后再传递给父组件
  const selected = getSelectedSpec(props.goods.specs);
  const selectedLength = selected.filter((item) => item).length;
  // 判断选中的规格的长度跟我们商品详情中的specs的长度是否一致
  if (selectedLength === props.goods.specs.length) {
    // console.log("---selected---选择完整了...", selected);
    // 获取选中三个规格组成的key
    const key = selected.join("★");

    // 获取规格对应的skuId（三个都选择了，一定只会找到一个）
    const [skuId] = pathMap[key];
    // console.log("---skuId---", skuId);

    // 传递给父组件
    emit("changeSku", skuId);
  } else {
    // 传递给父组件
    emit("changeSku", "");
  }
};

updateDisabledStatus(props.goods.specs, pathMap);
</script>
<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs" :key="item.name">
      <dt>{{ item.name }}</dt>
      <dd>
        <template v-for="subitem in item.values" :key="subitem.name">
          <img
            v-if="subitem.picture"
            :class="{ selected: subitem.selected, disabled: subitem.disabled }"
            :src="subitem.picture"
            alt=""
            :title="subitem.name"
            @click="toggleSelect(item, subitem)"
          />
          <span
            v-else
            @click="toggleSelect(item, subitem)"
            :class="{ selected: subitem.selected, disabled: subitem.disabled }"
            >{{ subitem.name }}</span
          >
        </template>
      </dd>
    </dl>
  </div>
</template>

<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 30px;
        padding: 0 20px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
